package com.example.demo.util;

import cfca.sadk.util.Base64;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.parser.Feature;
import com.alibaba.fastjson.serializer.SerializerFeature;

import java.io.ByteArrayOutputStream;
import java.io.FileInputStream;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;

public class TestHelper {
    private static final String MERCHANT_PFX_FILE  = TestHelper.class.getClassLoader().getResource("cert/merchant.pfx").getPath().substring(1);
    private static final String MERCHANT_SIGN_FILE = TestHelper.class.getClassLoader().getResource("cert/mechant_sign_sm2.sm2").getPath().substring(1);
    private static final String MERCHANT_ENC_FILE  = TestHelper.class.getClassLoader().getResource("cert/mechant_enc_sm2.sm2").getPath().substring(1);

    private static final String MERCHANT_SM2_PWD ="UMBPAY2022";

    private static final String PLATFORM_CER_FILE = TestHelper.class.getClassLoader().getResource("cert/platform.cer").getPath().substring(1);
    //	private static final String PLATFORM_SM2_CER_FILE = TestHelper.class.getResource("/resources/cert/platfrom_enc_sm2_soft.cer").getPath();
    private static final String PLATFORM_SM2_CER_FILE = TestHelper.class.getClassLoader().getResource("cert/platfrom_enc_sm2_soft.cer").getPath().substring(1);
    private static final String PLATFORM_SM2_SIGN_FILE = TestHelper.class.getClassLoader().getResource("cert/platfrom_sign_sm2_soft.cer").getPath().substring(1);

    public static boolean Verify(String resMsg) {
        String publicKey = TestHelper.readFile(PLATFORM_CER_FILE);
        RsaP1Util rsa = new RsaP1Util();
        String msg = null;
        try {
            msg = new String(rsa.openMessage(resMsg, MERCHANT_PFX_FILE,  "umbpay"));//返回数据
        } catch (Exception e) {
            e.getStackTrace();
        }
        System.out.println("retdata：" + msg);
        JSONObject Obj = JSON.parseObject(msg,Feature.OrderedField);
        String messageStr = Obj.getString("message");
        JSONObject messageObj = JSON.parseObject(messageStr,Feature.OrderedField);
        String dataStr = messageObj.getString("data");
        String signStr = messageObj.getString("sign");
        boolean verify = false;
        try {
            verify = rsa.rsaP1Verify(signStr, dataStr, publicKey.getBytes("UTF-8"));
        } catch (Exception e) {
            e.getStackTrace();
        }
        return verify;
    }

    public static String decode(String resMsg) {
        String publicKey = TestHelper.readFile(PLATFORM_CER_FILE);
        RsaP1Util rsa = new RsaP1Util();
        String msg = null;
        try {
            msg = new String(rsa.openMessage(resMsg, MERCHANT_PFX_FILE,  "umbpay"));//返回数据
        } catch (Exception e) {
            e.getStackTrace();
        }
        System.out.println("retdata：" + msg);
        JSONObject Obj = JSON.parseObject(msg,Feature.OrderedField);
        String messageStr = Obj.getString("message");
        JSONObject messageObj = JSON.parseObject(messageStr,Feature.OrderedField);
        String dataStr = messageObj.getString("data");
        String signStr = messageObj.getString("sign");
        boolean verify = false;
        try {
            verify = rsa.rsaP1Verify(signStr, dataStr, publicKey.getBytes("UTF-8"));
        } catch (Exception e) {
            e.getStackTrace();
        }
        return msg;
    }
    /**
     * 获取交易流水号
     * <p> Create Date: 2018-7-10 </p>
     * @return
     */
    public static String getTranFlow(String merchantid){
        return merchantid + DateTimeUtils.getNowDateStr(DateTimeUtils.DATETIME_FORMAT_YYYYMMDDHHMMSS) + getRandom();
    }
    /**
     *  生成6位随机数
     * @return
     */
    public static String getRandom() {
        String result = "";
        for (int i = 0; i < 6; i++) {
            int random = new Random().nextInt(10);
            result = result + random;
        }
        return result;
    }
    /**
     * 获取交易时间
     * <p> Create Date: 2018-7-10 </p>
     * @return
     */
    public static String getTime(){
        return DateTimeUtils.getNowDateStr(DateTimeUtils.DATETIME_FORMAT_HHMMSS);
    }
    /**
     * 获取交易日期
     * <p> Create Date: 2018-7-10 </p>
     * @return
     */
    public static String getDate(){
        return DateTimeUtils.getNowDateStr(DateTimeUtils.DATE_FORMAT_YYYYMMDD);
    }
    /**
     * 获取交易流水号
     * <p> Create Date: 2018-7-10 </p>
     * @return
     */



    /**
     *  格式化请求参数 签名并加密
     * @return
     */
    public static String format(Map<String,String> head, Map<String,String> body) {
        Map<String,Map<String,String>> data = new HashMap<String,Map<String,String>>();
        data.put("head", head);
        data.put("body", body);
        String dataJson = JSON.toJSONString(data,SerializerFeature.WriteNullStringAsEmpty);
        String sign =  sign(MERCHANT_PFX_FILE, "umbpay", dataJson);//消息签名
        Map<String,String> message = new HashMap<String,String>();
        message.put("sign", sign);
        message.put("data", dataJson);
        Map<String,Map<String,String>> messageMap = new HashMap<String,Map<String,String>>();
        messageMap.put("message", message);
        //把请求参数和签名对象进行json格式化
        String messageStr = JSON.toJSONString(messageMap,SerializerFeature.WriteNullStringAsEmpty);
        System.out.println("senddata："+ messageStr);//要发送数据
        String platform_publicKey = TestHelper.readFile(PLATFORM_CER_FILE);
        RsaP1Util rsa = new RsaP1Util();
        String envelopdata = null;
        try {
            envelopdata = new String(rsa.envelopMessageByCert(messageStr, platform_publicKey));
        } catch (Exception e) {
            e.getStackTrace();
        }
        return envelopdata;
    }


    public static String format(String dataJson) {
        String sign =  sign(MERCHANT_PFX_FILE, "umbpay", dataJson);//消息签名
        Map<String,String> message = new HashMap<String,String>();
        message.put("sign", sign);
        message.put("data", dataJson);
        Map<String,Map<String,String>> messageMap = new HashMap<String,Map<String,String>>();
        messageMap.put("message", message);
        //把请求参数和签名对象进行json格式化
        String messageStr = JSON.toJSONString(messageMap,SerializerFeature.WriteNullStringAsEmpty);
        System.out.println("senddata："+ messageStr);//要发送数据
        String platform_publicKey = TestHelper.readFile(PLATFORM_CER_FILE);
        RsaP1Util rsa = new RsaP1Util();
        String envelopdata = null;
        try {
            envelopdata = new String(rsa.envelopMessageByCert(messageStr, platform_publicKey));
        } catch (Exception e) {
            e.getStackTrace();
        }
        return envelopdata;
    }   /**
     *  签名
     * @return
     */
    public static String sign(String pfxPath, String pfxPwd, String msg) {
        RsaP1Util rsa = new RsaP1Util();
        String sign = null;
        try {
            sign = rsa.rsaP1Sign(msg, pfxPath, pfxPwd);
        } catch (Exception e) {
            e.getStackTrace();
        }
        return sign;
    }
    public static String readFile(String path) {
        try {
            FileInputStream e = new FileInputStream(path);
            byte[] buffer = new byte[8192];
            ByteArrayOutputStream bos = new ByteArrayOutputStream();
            boolean size = true;

            int size1;
            while ((size1 = e.read(buffer)) != -1) {
                bos.write(buffer, 0, size1);
            }

            return bos.toString();
        } catch (Exception arg4) {
            arg4.printStackTrace();
            return null;
        }
    }

    /**
     *  格式化请求参数 签名并加密
     * @return
     */
    public static String formatWithSm(Map<String,String> head, Map<String,String> body) {
        Map<String,Map<String,String>> data = new HashMap<String,Map<String,String>>();
        data.put("head", head);
        data.put("body", body);
        String dataJson = JSON.toJSONString(data,SerializerFeature.WriteNullStringAsEmpty);
        String sign =  signWithSm(MERCHANT_SIGN_FILE, MERCHANT_SM2_PWD, dataJson);//消息签名
        Map<String,String> message = new HashMap<String,String>();
        message.put("sign", sign);
        message.put("data", dataJson);
        Map<String,Map<String,String>> messageMap = new HashMap<String,Map<String,String>>();
        messageMap.put("message", message);
        //把请求参数和签名对象进行json格式化
        String messageStr = JSON.toJSONString(messageMap,SerializerFeature.WriteNullStringAsEmpty);
        System.out.println("senddata："+ messageStr);//要发送数据
        String envelopdata = null;
        try {
            String content = new String(Files.readAllBytes(Paths.get(PLATFORM_SM2_CER_FILE)));
            content = content.replaceAll("\\n", "");
            content = content.replace("\\r", "");
            envelopdata = new String(SM2Utils.envelopeMessage(messageStr, "SM4/ECB/PKCS7Padding",content));
        } catch (Exception e) {
            e.getStackTrace();
        }
        System.out.println("发送报文:"+envelopdata);
        return envelopdata;
    }

    /**
     *  签名
     * @return
     */
    public static String signWithSm(String sm2Path, String sm2Pwd, String msg) {
        String sign = null;
        try {
            sign = SM2Utils.P7SignMessageDetach("sm3WithSM2Encryption",new String(Base64.encode(msg.getBytes("UTF-8"))),sm2Path,sm2Pwd);
        } catch (Exception e) {
            e.getStackTrace();
        }
        return sign;
    }

    public static boolean VerifyWithSm(String resMsg) {
        String msg = null;
        try {
            msg = new String(SM2Utils.openEvelopedMessage(resMsg, MERCHANT_ENC_FILE,  MERCHANT_SM2_PWD));//返回数据
        } catch (Exception e) {
            e.getStackTrace();
        }
        System.out.println("验签retdata：" + msg);
        JSONObject Obj = JSON.parseObject(msg,Feature.OrderedField);
        String messageStr = Obj.getString("message");
        JSONObject messageObj = JSON.parseObject(messageStr,Feature.OrderedField);
        String dataStr = messageObj.getString("data");
        System.out.println("验签原串"+dataStr);
        String signStr = messageObj.getString("sign");
        boolean verify = false;
        try {
            String content = new String(Files.readAllBytes(Paths.get(PLATFORM_SM2_SIGN_FILE)));
            content = content.replaceAll("\n", "");
            content = content.replace("\r", "");
            System.out.println("读取到的平台公钥:"+content);
            verify = SM2Utils.P7VerifyMessageDetach(new String(Base64.encode(dataStr.getBytes("UTF-8"))), signStr,content);
        } catch (Exception e) {
            System.err.println("验签异常");
            e.getStackTrace();
        }
        return verify;
    }
}